﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Specter
{
	class HotKey:System.Windows.Forms.Control
	{

		private int Counter;

		[System.Runtime.InteropServices.DllImport("user32.dll")]
		public static extern bool RegisterHotKey (
		IntPtr hWnd , // handle to window
		int id , // hot key identifier
		uint fsModifiers , // key-modifier options
		Keys vk // virtual-key code
		);

		[System.Runtime.InteropServices.DllImport("user32.dll")]
		public static extern bool UnregisterHotKey (
		IntPtr hWnd , // handle to window
		int id // hot key identifier
		);

		/// <summary>
		/// A dictionary that use hot key's name as Key and hot key's id as Value.
		/// </summary>
		private Dictionary<string,int> RegisteredHotKeysID;
		/// <summary>
		/// A dictionary that use hot key's id as Key and callback method as Value.
		/// </summary>
		private Dictionary<int,VoidMethod> RegisteredHotKeysMethod;

		/// <summary>
		/// Listen to window's message.
		/// </summary>
		/// <param name="m"></param>
		protected override void WndProc ( ref Message m )
		{
			if ( m.Msg == (int)0x0312 )
				this.RegisteredHotKeysMethod[m.WParam.ToInt32()]();
			base.WndProc(ref m);
		}



		/// <summary>
		/// Contrustor.
		/// </summary>
		public HotKey ( )
		{
			Counter = 0;
			this.RegisteredHotKeysID = new Dictionary<string , int>();
			this.RegisteredHotKeysMethod = new Dictionary<int , VoidMethod>();
		}

		/// <summary>
		/// Represents the a void type method.
		/// </summary>
		public delegate void VoidMethod ( );

		/// <summary>
		/// Represents key modifiers.
		/// </summary>
		public enum KeyModifiers : uint
		{
			None = 0 ,
			Alt = 1 ,
			Control = 2 ,
			Shift = 4 ,
			Windows = 8
		}

		/// <summary>
		/// Register a hot key.
		/// </summary>
		/// <param name="HotkeyName">Specifies the hot key's name. You can use whatever you like.</param>
		/// <param name="KeyModifier">Specifies key modifier.</param>
		/// <param name="Key">Specifies the key code of the hot key.</param>
		/// <param name="CallBack">Specifies the callback method which is called when the registered key is called.</param>
		/// <returns>Specifies whether registeration is successful.</returns>
		public bool RegisterHotKey ( string HotkeyName , KeyModifiers KeyModifier , Keys Key , VoidMethod CallBack )
		{
			int id=Counter++;
			bool r=RegisterHotKey(Handle , id , (uint)KeyModifier , Key);
			if ( r )
			{
				this.RegisteredHotKeysID.Add(HotkeyName , id);
				this.RegisteredHotKeysMethod.Add(id , CallBack);
			}
			return r;
		}

		/// <summary>
		/// Unregister a hot key.
		/// </summary>
		/// <param name="HotkeyName">Specifies the hot key's name used when this hot key was registered.</param>
		/// <returns>Specifies whether unregisteration is successful.</returns>
		public bool UnRegisterHotKey ( string HotkeyName )
		{
			bool r = UnregisterHotKey(Handle , this.RegisteredHotKeysID[HotkeyName]);
			if ( r )
			{
				this.RegisteredHotKeysMethod.Remove(this.RegisteredHotKeysID[HotkeyName]);
				this.RegisteredHotKeysID.Remove(HotkeyName);
				Counter--;
			}
			return r;
		}

	}
}
